package com.reverie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reverie.entity.Menu;
import com.reverie.entity.RoleMenu;
import com.reverie.entity.User;
import com.reverie.mapper.RoleMenuMapper;
import com.reverie.service.IMenuService;
import com.reverie.service.IRoleMenuService;
import com.reverie.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {

    @Resource
    private IMenuService menuService;
    @Resource
    private IUserService userService;

    @Override
    public List<RoleMenu> listByRoleId(Integer roleId) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RoleMenu::getRoleId,roleId);
        return list(wrapper);
    }

    @Override
    public List<Menu> listMenuTreeByUserId(Integer userId) {
        User user = userService.getById(userId);
        List<RoleMenu> roleMenuList = listByRoleId(user.getRoleId());
        List<Integer> menuIds = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        List<Menu> menuList = menuService.listByIds(menuIds);

        List<Menu> rootMenus = menuList.stream().filter(item -> item.getParentId() == null || item.getParentId().equals(0)).sorted(Comparator.comparingInt(Menu::getSortId)).collect(Collectors.toList());
        Map<Integer,List<Menu>> menuMap = menuList.stream().collect(Collectors.groupingBy(Menu::getParentId));
        rootMenus.forEach(menu -> {
            List<Menu> childMenus = menuMap.getOrDefault(menu.getId(),new ArrayList<>()).stream().sorted(Comparator.comparingInt(Menu::getSortId)).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(childMenus)){
                childMenus.forEach(child -> {
                    child.setChildren(menuMap.getOrDefault(child.getId(),new ArrayList<>()));
                });
            }
            menu.setChildren(childMenus);
        });

        return rootMenus;
    }

    @Override
    public void removeByRoleId(Integer roleId) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RoleMenu::getRoleId,roleId);
        remove(wrapper);
    }

    @Override
    public List<RoleMenu> listByRoleIds(Set<Integer> roleIds) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(RoleMenu::getRoleId,roleIds);
        return list(wrapper);
    }
}
